package org.hxzon.tapestry5.util;

import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.internal.services.RequestConstants;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.services.Dispatcher;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.Response;
import org.apache.tapestry5.services.assets.AssetRequestHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyAssetDispatcher implements Dispatcher {
    private Logger logger = LoggerFactory.getLogger(MyAssetDispatcher.class);
    /**
     * Keyed on extended path name, which includes the pathPrefix first and a trailing slash.
     */
    private final Map<String, AssetRequestHandler> pathToHandler = CollectionFactory.newMap();

    /**
     * List of path prefixes in the pathToHandler, sorted be descending length.
     */
    private final List<String> assetPaths = CollectionFactory.newList();

    private final String pathPrefix;

    public MyAssetDispatcher(Map<String, AssetRequestHandler> configuration,

    @Symbol(SymbolConstants.APPLICATION_VERSION) String applicationVersion,

    @Symbol(SymbolConstants.APPLICATION_FOLDER) String applicationFolder,

    @Symbol(SymbolConstants.ASSET_PATH_PREFIX) String assetPathPrefix) {
        String folder = applicationFolder.equals("") ? "" : "/" + applicationFolder;

        this.pathPrefix = folder + assetPathPrefix + applicationVersion + "/";

        for (String path : configuration.keySet()) {
            String extendedPath = this.pathPrefix + path + "/";

            pathToHandler.put(extendedPath, configuration.get(path));

            assetPaths.add(extendedPath);
        }

        // Sort by descending length

        Collections.sort(assetPaths, new Comparator<String>() {
            public int compare(String o1, String o2) {
                return o2.length() - o1.length();
            }
        });
    }

    public boolean dispatch(Request request, Response response) throws IOException {
        String path = request.getPath();
        path = StringUtils.deleteWhitespace(path);
        logger.trace(path);
        if (path.contains("/css/") && !path.contains("/assets/")) {
            path = path.substring(path.indexOf("/css"));
            path = request.getContextPath() + pathPrefix + RequestConstants.CONTEXT_FOLDER + path;
            logger.trace("send redirect:" + path);
            response.sendRedirect(path);
            return true;
        }

        return false;
    }

}
